/** @file rsa.h
@brief This module contains the RSA algorithm */

/** \defgroup ProcessSteps Process steps
@{ */

/** \defgroup AuthObjects Authentication objects
@{ */

/** \defgroup RsaMod RSA object
@{ */


/*
   RSA.H - header file for RSA cryptographic toolkit
   Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
   Security, Inc. All rights reserved.
 */

#ifndef __RSA_H__
#define __RSA_H__

#ifdef __BORLANDC__
 #include <mem.h>
#endif

#ifdef _PC_
 #include <memory.h>
#endif

/***************************************************************
  RSATOOLS.H
   Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
   Security, Inc. All rights reserved.
 ***************************************************************/
/* Type definitions. */
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
typedef UINT4 RSA_DIGIT;
typedef UINT2 RSA_HALF_DIGIT;

/* Constants.
   Note: MAX_RSA_DIGITS is long enough to hold any RSA modulus, plus
   one more digit as required by R_GeneratePEMKeys (for n and phiN,
   whose lengths must be even). All natural numbers have at most
   MAX_RSA_DIGITS digits, except for double-length intermediate values
   in RSA_Mult (t), RSA_ModMult (t), RSA_ModInv (w), and RSA_Div (c). */

/*----------------------------------------
    RSA key lengths.
 -----------------------------------------*/


/*
 CONVERSIONS
   RSA_Decode (a, digits, b, len)     Decodes character string b into a.
   RSA_Encode (a, len, b, digits)     Encodes a into character string b.
 ASSIGNMENTS
   RSA_Assign (a, b, digits)          Assigns a = b.
   RSA_ASSIGN_DIGIT (a, b, digits)    Assigns a = b, where b is a digit.
   RSA_AssignZero (a, b, digits)      Assigns a = 0.
   RSA_Assign2Exp (a, b, digits)      Assigns a = 2^b.
 ARITHMETIC OPERATIONS
   RSA_Add (a, b, c, digits)          Computes a = b + c.
   RSA_Sub (a, b, c, digits)          Computes a = b - c.
   RSA_Mult (a, b, c, digits)         Computes a = b * c.
   RSA_Mod (a,b,bDigits,c,cDigits)    Computes a = b mod c.
   RSA_ModMult (a, b, c, d, digits)   Computes a = b * c mod d.
   RSA_ModExp(a,b,c,cDigits,d,dDigits)Computes a = b^c mod .
   RSA_ModInv (a, b, c, digits)       Computes a = 1/b mod c.
   RSA_Gcd (a, b, c, digits)          Computes a = gcd (b, c).
 OTHER OPERATIONS
   RSA_EVEN (a, digits)               Returns 1 iff a is even.
   RSA_Cmp (a, b, digits)             Returns sign of a - b.
   RSA_EQUAL (a, digits)              Returns 1 iff a = b.
   RSA_Zero (a, digits)               Returns 1 iff a = 0.
   RSA_Digits (a, digits)             Returns significant length of a in digits.
   RSA_Bits (a, digits)               Returns significant length of a in bits. */

void RSA_Decode        (RSA_DIGIT *, unsigned int, unsigned char *, unsigned int);
void RSA_Encode        (unsigned char *, unsigned int, RSA_DIGIT *, unsigned int);
void RSA_Assign        (RSA_DIGIT *, RSA_DIGIT *, unsigned int);
void RSA_AssignZero    (RSA_DIGIT *, unsigned int);
void RSA_Assign2Exp    (RSA_DIGIT *, unsigned int, unsigned int);
RSA_DIGIT RSA_Add      (RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, unsigned int);
RSA_DIGIT RSA_Sub      (RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, unsigned int);
void RSA_Mult          (RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, unsigned int);
void RSA_Mod           (RSA_DIGIT *, RSA_DIGIT *, unsigned int, RSA_DIGIT *, unsigned int);
void RSA_ModMult       (RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, unsigned int);
void RSA_ModExp        (RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, unsigned int, RSA_DIGIT *, unsigned int);
void RSA_ModInv        (RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, unsigned int);
void RSA_Gcd           (RSA_DIGIT *, RSA_DIGIT *, RSA_DIGIT *, unsigned int);
int RSA_Cmp            (RSA_DIGIT *, RSA_DIGIT *, unsigned int);
int RSA_Zero           (RSA_DIGIT *, unsigned int);
unsigned int RSA_Bits  (RSA_DIGIT *, unsigned int);
unsigned int RSA_Digits(RSA_DIGIT *, unsigned int);
void RSA_DigitMult     (RSA_DIGIT [2], RSA_DIGIT, RSA_DIGIT);
void RSA_DigitDiv      (RSA_DIGIT *, RSA_DIGIT [2], RSA_DIGIT);
#define RSA_ASSIGN_DIGIT(a, b, digits) {RSA_AssignZero (a, digits); a[0] = b;}
/**  Data error code */
#define RE_DATA  0xFFFE
/**  Len error code */
#define RE_LEN   0xFFFD

/** RSA public key structure  */
typedef struct
{
  unsigned int  bits;                          /**< length in bits of modulus */
  unsigned char modulus  [MAX_RSA_MODULUS_LEN];/**< modulus */
  unsigned char exponent [MAX_RSA_MODULUS_LEN];/**< public exponent */

} R_RSA_PUBLIC_KEY;

/** RSA public-key decryption, according to PKCS #1. 
@param output output decryption 
@param outputLen output lenght
@param input input crypted data
@param inputLen input data length 
@param publicKey public key
@return OK if success */
int RSAPublicDecrypt ( unsigned char *output, unsigned int *outputLen,
                       unsigned char *input,  unsigned int inputLen,
                       R_RSA_PUBLIC_KEY *publicKey);

#endif
/** @} */
/** @} */
/** @} */
